//
//  ARCAndMemoryManagementTest.h
//  test_simple_project
//
//  ARC和内存管理语法特性测试文件
//  测试自动引用计数、内存管理修饰符和最佳实践
//

#import <Foundation/Foundation.h>

#pragma mark - 前向声明

@class ARCTestDelegate;
@class ARCTestChild;
@class ARCTestParent;

#pragma mark - 内存管理修饰符测试协议

@protocol ARCMemoryManagementProtocol <NSObject>

@optional
- (void)memoryManagementCallback;
- (void)weakReferenceCallback:(id)sender;

@end

#pragma mark - 主测试类

@interface ARCAndMemoryManagementTest : NSObject

#pragma mark - 强引用属性 (__strong)

// 默认情况下，对象属性都是强引用
@property (strong, nonatomic) NSString *strongString;
@property (strong, nonatomic) NSMutableArray *strongArray;
@property (strong, nonatomic) NSMutableDictionary *strongDictionary;
@property (strong, nonatomic) ARCTestChild *strongChild;

// 显式声明强引用
@property (strong, nonatomic) id<ARCMemoryManagementProtocol> strongDelegate;

#pragma mark - 弱引用属性 (__weak)

// 弱引用属性，防止循环引用
@property (weak, nonatomic) id<ARCMemoryManagementProtocol> weakDelegate;
@property (weak, nonatomic) ARCTestParent *weakParent;
@property (weak, nonatomic) id weakTarget;

// 弱引用集合（需要特殊处理）
@property (strong, nonatomic) NSHashTable *weakObjectsHashTable;
@property (strong, nonatomic) NSMapTable *weakKeysMapTable;

#pragma mark - 不安全未保留引用 (__unsafe_unretained)

// 不安全的未保留引用，不会自动置nil
@property (unsafe_unretained, nonatomic) id unsafeUnretainedTarget;
@property (unsafe_unretained, nonatomic) ARCTestDelegate *unsafeDelegate;

#pragma mark - 自动释放引用 (__autoreleasing)

// 用于方法参数，特别是NSError **类型
- (BOOL)performOperationWithError:(NSError * __autoreleasing *)error;
- (BOOL)validateInputWithError:(NSError * __autoreleasing *)error;

#pragma mark - 循环引用测试方法

// 创建和解决循环引用
- (void)demonstrateStrongReferenceCycle;
- (void)demonstrateWeakReferencePattern;
- (void)demonstrateParentChildRelationship;

#pragma mark - Block内存管理

// Block相关的内存管理
- (void)demonstrateBlockMemoryManagement;
- (void)demonstrateBlockWeakSelfPattern;
- (void)demonstrateBlockStrongWeakDance;

#pragma mark - 集合类内存管理

// 集合类的内存管理
- (void)demonstrateCollectionMemoryManagement;
- (void)demonstrateWeakCollections;
- (void)demonstrateCopySemantics;

#pragma mark - 自动释放池

// 自动释放池的使用
- (void)demonstrateAutoreleasePool;
- (void)demonstrateNestedAutoreleasePools;
- (void)demonstrateAutoreleasePoolInLoop;

#pragma mark - 内存管理最佳实践

// 内存管理最佳实践
- (void)demonstratePropertyMemorySemantics;
- (void)demonstrateMethodParameterMemorySemantics;
- (void)demonstrateReturnValueMemorySemantics;

#pragma mark - 内存泄漏检测和调试

// 内存泄漏检测
- (void)demonstrateMemoryLeakDetection;
- (void)demonstrateMemoryDebugging;
- (void)logMemoryUsage;

@end

#pragma mark - 测试辅助类

/**
 * 父类，用于测试父子关系中的内存管理
 */
@interface ARCTestParent : NSObject

@property (strong, nonatomic) NSString *parentName;
@property (strong, nonatomic) NSMutableArray<ARCTestChild *> *children;
@property (weak, nonatomic) id<ARCMemoryManagementProtocol> delegate;

- (instancetype)initWithName:(NSString *)name;
- (void)addChild:(ARCTestChild *)child;
- (void)removeChild:(ARCTestChild *)child;
- (void)removeAllChildren;

@end

/**
 * 子类，用于测试父子关系中的内存管理
 */
@interface ARCTestChild : NSObject

@property (strong, nonatomic) NSString *childName;
@property (weak, nonatomic) ARCTestParent *parent; // 弱引用防止循环引用
@property (strong, nonatomic) NSMutableArray *toys;

- (instancetype)initWithName:(NSString *)name parent:(ARCTestParent *)parent;
- (void)addToy:(NSString *)toy;
- (void)playWithToys;

@end

/**
 * 委托类，用于测试委托模式中的内存管理
 */
@interface ARCTestDelegate : NSObject <ARCMemoryManagementProtocol>

@property (strong, nonatomic) NSString *delegateName;
@property (weak, nonatomic) ARCAndMemoryManagementTest *owner; // 弱引用防止循环引用

- (instancetype)initWithName:(NSString *)name owner:(ARCAndMemoryManagementTest *)owner;

@end

/**
 * 观察者类，用于测试观察者模式中的内存管理
 */
@interface ARCTestObserver : NSObject

@property (strong, nonatomic) NSString *observerName;
@property (weak, nonatomic) id observedObject; // 弱引用被观察对象

- (instancetype)initWithName:(NSString *)name;
- (void)startObserving:(id)object;
- (void)stopObserving;

@end

#pragma mark - 内存管理工具类

/**
 * 内存管理工具类
 */
@interface ARCMemoryUtils : NSObject

// 弱引用集合创建
+ (NSHashTable *)createWeakObjectsHashTable;
+ (NSMapTable *)createWeakKeysStrongValuesMapTable;
+ (NSMapTable *)createStrongKeysWeakValuesMapTable;

// 内存使用统计
+ (NSUInteger)getCurrentMemoryUsage;
+ (void)logMemoryStatistics;
+ (void)forceGarbageCollection;

// 循环引用检测
+ (BOOL)detectRetainCycleInObject:(id)object;
+ (NSArray *)findRetainCyclePathFromObject:(id)object;

@end

#pragma mark - 内存管理常量和宏

// 内存管理相关常量
extern NSString * const ARCMemoryManagementNotification;
extern NSString * const ARCMemoryWarningNotification;

// 内存管理宏定义
#define ARC_WEAK_SELF __weak typeof(self) weakSelf = self
#define ARC_STRONG_SELF __strong typeof(weakSelf) strongSelf = weakSelf

#define ARC_SAFE_CALL(target, selector, ...) \
    do { \
        if (target && [target respondsToSelector:selector]) { \
            [target performSelector:selector withObject:__VA_ARGS__]; \
        } \
    } while(0)

// 自动释放池宏
#define ARC_AUTORELEASE_POOL_BEGIN @autoreleasepool {
#define ARC_AUTORELEASE_POOL_END }

// 内存调试宏
#ifdef DEBUG
    #define ARC_LOG_DEALLOC NSLog(@"[DEALLOC] %@ deallocated", NSStringFromClass([self class]))
    #define ARC_LOG_MEMORY_WARNING NSLog(@"[MEMORY] Memory warning received")
#else
    #define ARC_LOG_DEALLOC
    #define ARC_LOG_MEMORY_WARNING
#endif
